﻿#include <iostream>
class Animal {
public:
    int Age;
    void virtual beAct(Animal* anm) {//需要加上virtual才能动态多态调用，不加上的话永远调用指针类的beAct函数
        std::cout << "动物被攻击！" << std::endl;
    }
};
class Human :public Animal {
public:
    int Money=1;
    void doit() {
        std::cout << "Do it!" << std::endl;
    }
    void beAct(Animal* anm) {//需要加上virtual才能实现，但是这里不加virtual也能实现，因为指针bA原本就是Animal类，Animal类的beAct函数是虚函数
        std::cout << "人被攻击！" << std::endl;
    }
};
void BeAct(Human* R) {

}
void BeAct(Animal* anm) {

}

int main()
{
    Human laow;
    laow.Age = 350;
    laow.Money = 250;
    //Animal anm = laow;//内存切片，子类->父类，向上转型
    //Human laowan = anm;//报错，父类->子类，向下转型，因为Human类相比Animal有更多内容，多转小的话会访问不属于Human类的内存空间

    Animal* anm = &laow;//通过指针或引用表达laow中Animal的特征
    Human* hman = (Human*)anm;//父类->子类，存在访问不属于该对象的内存地址的风险，最好用来访问不涉及子类的变量访问的函数

    hman->doit();//向下转型调用子类函数，能正常调用
    Human* hman1 = (Human*)(new Animal);
    hman1->doit();
    std::cout << hman1->Money << std::endl;//-33686019，基类强制转换派生类的话，虽然能调用派生类的函数，但是派生类的变量没有初始化
    //std::cout << anm.Age;

    Animal hu;
    Human laow1;
    Animal& anm1 = laow1;//引用转换
    //Human& lao1 = dynamic_cast<Human&>(hu);//抛出异常，但是可以过编译，指针可以有空指针，引用不能有空引用，此时因为基类转派生类导致转换失败返回空指针，所以异常
    //std::cout << &lao1 << std::endl;

    Human laowa;
    Animal dog;

    //静态多态，通过重载或模板实现
    BeAct(&laowa);
    BeAct(&dog);


    int id = 1;
    Animal* bA;
    //std::cin >> id;
    //动态多态
    if (id) {//通过id输入来决定Animal类指针bA指向什么类
        bA = &dog;
    }
    else bA = &laowa;

    bA->beAct(&dog);
}